package com.yugao.fintech.antelope.auth.model.bo;

import cn.hutool.core.util.StrUtil;
import com.yugao.fintech.antelope.base.security.utils.SecurityUtils;
import com.yugao.fintech.antelope.base.model.constants.UserCons;
import com.yugao.fintech.antelope.base.model.enums.AuthErrorEnum;
import com.yugao.fintech.antelope.base.model.module.auth.LoginUser;
import com.yugao.fintech.framework.assistant.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;

import java.util.Objects;
import java.util.function.Function;

/**
 * 检查登录用户信息
 */
@Slf4j
public class CheckLoginUser {
    private final LoginUser loginUser;
    private final String loginAccount;
    private final String loginPassword;

    private AuthErrorEnum authErrorEnum;

    public static CheckLoginUser of(String loginAccount, String loginPassword, LoginUser loginUser) {
        return new CheckLoginUser(loginAccount, loginPassword, loginUser);
    }

    private CheckLoginUser(String loginAccount, String loginPassword, LoginUser loginUser) {
        this.loginUser = loginUser;
        this.loginAccount = loginAccount;
        this.loginPassword = loginPassword;

        if (StringUtils.isNull(loginUser)) {
            throw new BadCredentialsException("登录用户：" + this.loginAccount + " 不存在");
        }
    }

    public CheckLoginUser isDeleted() {
//        if (UserStatusEnum.DELETED.getCode().equals(userDetails.getDelFlag())) {
//            throw new BizException("对不起，您的账号：" + userName + " 已被删除");
//        }
        return this;
    }

    public CheckLoginUser isDisabled() {
        String status = loginUser.getStatus();
        if (Objects.isNull(this.authErrorEnum) && StrUtil.equals(status, UserCons.Status.DISABLE)) {
            log.warn("用户 {} 已被停用", this.loginAccount);
            this.authErrorEnum = AuthErrorEnum.USER_DISABLE;
        }
        return this;
    }

    /**
     * 匹配密码是否正确
     */
    public CheckLoginUser matchPassword() {
        if (Objects.isNull(this.authErrorEnum) &&
                !SecurityUtils.matchesPassword(this.loginPassword, loginUser.getAccount().getPassword())) {
            log.debug("Failed to authenticate since password does not match stored value, loginPassword: " + loginPassword);
            this.authErrorEnum = AuthErrorEnum.USER_USERNAME_OR_PASSWORD_ERROR;
        }
        return this;
    }

    public void throwError(Function<AuthErrorEnum, RuntimeException> biConsumer) {
        if (Objects.nonNull(this.authErrorEnum)) {
            throw biConsumer.apply(this.authErrorEnum);
        }
    }
}
